using System;
using System.Collections.Generic;
using System.Text;

namespace Wrath.Xml.Objects.Controls
{
    public abstract class WindowControl
    {
        protected string name;
        public string Name { get { return name; } }

        protected string source;
        public string Source { get { return source; } }

        protected IControlPosition position;
        public IControlPosition Position { get { return position; } }

        protected ControlFrame frame;
        public ControlFrame Frame { get { return frame; } }

        protected List<string> dropTypes;
        protected ControlStateFrame stateFrame;
        protected ControlTabTarget tabTarget;
        protected ControlTooltip tooltip;
        protected bool invisible = false;
        protected bool disable = false;

        protected List<Element> customProperties;

        protected void Parse(Element element)
        {
            Attribute attribute = element.FindAttribute("name");
            if (attribute != null)
            {
                name = attribute.Value.Substring(0);
            }

            attribute = element.FindAttribute("source");
            if (attribute != null)
            {
                source = attribute.Value.Substring(0);
            }

            Element subElement = element.FindFirstElement("bounds", false);
            if (subElement != null)
            {
                position = new ControlBounds(subElement);
                element.ChildElements.Remove(subElement);
            }
            else
            {
                subElement = element.FindFirstElement("anchored", false);
                if (subElement != null)
                {
                    position = new ControlAnchor(subElement);
                    element.ChildElements.Remove(subElement);
                }
            }

            subElement = element.FindFirstElement("frame", false);
            if (subElement != null)
            {
                frame = new ControlFrame(subElement);
                element.ChildElements.Remove(subElement);
            }

            subElement = element.FindFirstElement("droptypes", false);
            if (subElement != null)
            {
                dropTypes = new List<string>();
                foreach (Element child in subElement.ChildElements)
                {
                    if (child.Name.ToLower() == "type")
                    {
                        dropTypes.Add(child.Value.Substring(0));
                    }
                }

                element.ChildElements.Remove(subElement);
            }

            subElement = element.FindFirstElement("stateframe", false);
            if (subElement != null)
            {
                stateFrame = new ControlStateFrame(subElement);
                element.ChildElements.Remove(subElement);
            }

            // tabtarget
            subElement = element.FindFirstElement("tabtarget", false);
            if (subElement != null)
            {
                tabTarget = new ControlTabTarget(subElement);
                element.ChildElements.Remove(subElement);
            }

            // tooltip
            subElement = element.FindFirstElement("tooltip", false);
            if (subElement != null)
            {
                tooltip = new ControlTooltip(subElement);
                element.ChildElements.Remove(subElement);
            }

            // invisible
            subElement = element.FindFirstElement("invisible", false);
            if (subElement != null)
            {
                invisible = true;
                element.ChildElements.Remove(subElement);
            }

            // disabled
            subElement = element.FindFirstElement("disable", false);
            if (subElement != null)
            {
                disable = true;
                element.ChildElements.Remove(subElement);
            }
        }

        protected void Finalise(Element element)
        {
            customProperties = element.ChildElements;
        }

        protected void Commit(Element element)
        {
            if (!String.IsNullOrEmpty(name))
            {
                Attribute attribute = new Attribute();
                attribute.Name = "name";
                attribute.Value = name;

                element.Attributes.Add(attribute);
            }

            if (!String.IsNullOrEmpty(source))
            {
                Attribute attribute = new Attribute();
                attribute.Name = "source";
                attribute.Value = source;

                element.Attributes.Add(attribute);
            }

            if (position != null)
            {
                position.Commit();
                element.ChildElements.Add(position.SourceElement);
            }

            if (frame != null)
            {
                frame.Commit();
                element.ChildElements.Add(frame.SourceElement);
            }

            if (dropTypes != null && dropTypes.Count > 0)
            {
                Element drops = new Element("droptypes");
                foreach (string type in dropTypes)
                {
                    Element dt = new Element("type");
                    dt.Value = type;
                    drops.ChildElements.Add(dt);
                }

                element.ChildElements.Add(drops);
            }

            if (stateFrame != null)
            {
                stateFrame.Commit();
                element.ChildElements.Add(stateFrame.SourceElement);
            }

            if (tabTarget != null)
            {
                tabTarget.Commit();
                element.ChildElements.Add(tabTarget.SourceElement);
            }

            if (tooltip != null)
            {
                tooltip.Commit();
                element.ChildElements.Add(tooltip.SourceElement);
            }

            if (invisible)
            {
                Element inv = new Element("invisible");
                element.ChildElements.Add(inv);
            }

            if (disable)
            {
                Element dis = new Element("disable");
                element.ChildElements.Add(dis);
            }            
        }

        protected void CommitFinalize(Element element)
        {
            foreach (Element prop in customProperties)
            {
                element.ChildElements.Add(prop);
            }
        }

    }
}
